package org.spiderflow.config.permission;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spiderflow.common.redis.userinfo.RedisUserInfoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

/**
 * Created by Nicky.Tang on 2020/4/1 3:47 PM
 * 检查redis连接状态 -aop实现类
 *
 * @since 02.12.13.z01
 */
@Component
@Aspect
public class PermissionCheckAspect {

    private static final Logger logger = LoggerFactory.getLogger(PermissionCheckAspect.class);

    @Autowired
    RedisUserInfoUtil redisUserInfoUtil;

    @Around(value = "@within(org.spiderflow.config.permission.PermissionCheck))")
//    @Around(value = "execution(* org.spiderflow.*.controller.*.*(..))")
    public Object arround(ProceedingJoinPoint joinPoint) throws Exception, Throwable {
        Object res = null;
        HttpServletRequest request = currentRequest();
        //1. 检查权限
        PermissionCheck permissionCheckClass = joinPoint.getTarget().getClass().getAnnotation(PermissionCheck.class);
        if (permissionCheckClass != null) {
            redisUserInfoUtil.checkPer(permissionCheckClass.perCode());
        }
        PermissionCheck permissionCheckMethod = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(PermissionCheck.class);
        if (permissionCheckMethod != null) {
            redisUserInfoUtil.checkPer(permissionCheckMethod.perCode());
        }

        //2. 执行目标方法
        res = joinPoint.proceed();
        return res;
    }

    private HttpServletRequest currentRequest() {
        // Use getRequestAttributes because of its return null if none bound
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return Optional.ofNullable(servletRequestAttributes).map(ServletRequestAttributes::getRequest).orElse(null);
    }
}
